2026-09-27 · class-notes, linux, bash, readline, command-history, tab-completion, kill-and-yank
Full class notes for TLCL ch. 8: readline cursor movement and editing, cut/paste (kill and yank), tab completion, and command history/expansion.
How these notes were made: the material supplied for this lesson was the chapter's own heading list — "Command Line Editing", "Cursor Movement", "Modifying Text", "Cutting and Pasting (Killing and Yanking) Text", "Command Completion", "Using History", "Searching History", "History Expansion" — with an explicit instruction to draft the content from general knowledge rather than a transcript. These notes follow that structure, but the explanations, keybindings and examples are written from general knowledge of bash's default (emacs-mode) readline behaviour, not reproduced or paraphrased from William Shotts's actual book text, which was not supplied. Worth checking against your own copy of the chapter for Shotts's specific wording and any examples particular to his presentation.
Class notes · The Linux Command Line (3rd ed.), William Shotts · Chapter 8
Quick reference: the short version of this lesson lives in the The Linux Command Line resource sheets. This follows Chapter 7 (Seeing the World as the Shell Sees It) — that chapter covered how the shell interprets what you type; this one covers typing it faster, through the line-editing engine bash uses, called readline.
By the end of these notes you should be able to:
Bash does not simply collect raw keystrokes — it uses a library called readline to provide proper line editing: moving the cursor, deleting and rearranging text, and recalling history, all without leaving the keyboard. By default, readline uses emacs-style keybindings (an alternative vi-style mode also exists, but emacs-style is the default and what this chapter covers).
Most of these shortcuts use Control (written Ctrl-x) or Alt/Meta
(written Alt-x) held with another key.
| Keys | Moves |
|---|---|
Ctrl-A |
To the beginning of the line |
Ctrl-E |
To the end of the line |
Ctrl-F (or Right Arrow) |
Forward one character |
Ctrl-B (or Left Arrow) |
Backward one character |
Alt-F |
Forward one word |
Alt-B |
Backward one word |
Ctrl-L |
Clears the screen (cursor stays at the current line) |
Exam tip:
Ctrl-A/Ctrl-E(start/end of line) are worth memorising first — they are by far the most useful pair for quickly jumping to either end of a long command you are editing.
| Keys | Effect |
|---|---|
Ctrl-D (or Delete) |
Delete the character under/after the cursor |
Backspace |
Delete the character before the cursor |
Ctrl-T |
Transpose (swap) the two characters around the cursor |
Alt-T |
Transpose the two words before the cursor |
Alt-L |
Convert the word from the cursor onward to lowercase |
Alt-U |
Convert the word from the cursor onward to uppercase |
Alt-C |
Capitalise the word from the cursor onward |
Example of Ctrl-T (transpose characters):
before: ls -la /hmoe/user (cursor just after 'o' in "hmoe")
Ctrl-T: ls -la /home/user (the two characters around the
cursor have swapped)
Readline calls cutting text killing, and pasting it back yanking — older terminology than "cut and paste," but functionally the same idea. Killed text goes into a small internal buffer (the kill ring) that you can yank back later.
| Keys | Effect |
|---|---|
Ctrl-K |
Kill from the cursor to the end of the line |
Ctrl-U |
Kill from the cursor to the beginning of the line |
Ctrl-W |
Kill the word before the cursor |
Alt-D |
Kill the word after/under the cursor |
Ctrl-Y |
Yank (paste) the most recently killed text at the cursor |
Kill and yank in practice:
ls -la /var/log/syslog (cursor at the end of the line)
Ctrl-U -> kills the whole line to the buffer
(empty line)
cd /tmp
Ctrl-Y -> yanks "ls -la /var/log/syslog" back,
inserted wherever the cursor now is
In the real world:
Ctrl-Ufollowed later byCtrl-Yis a quick way to "park" a half-typed command, run something else, then bring the original command back exactly as it was.
Pressing Tab triggers completion: bash tries to fill in the rest of whatever you are typing — a command name, a filename, a variable, and more, depending on context.
$ cd /etc/net<Tab>
$ cd /etc/network/
$ ls doc<Tab><Tab>
document.txt documentation/ docs.pdf
Exam tip: completion is context-aware — at the start of a line it completes command names; after a command, it typically completes filenames or, for some commands, other relevant arguments.
Bash keeps a running history of commands you have typed, letting you recall and reuse them without retyping.
| Keys | Effect |
|---|---|
Ctrl-P (or Up Arrow) |
Recall the previous command |
Ctrl-N (or Down Arrow) |
Move to the next (more recent) command |
The history command lists your stored command history with line numbers:
$ history
501 cd /var/log
502 ls -la
503 tail -f syslog
Rather than stepping backward one command at a time, you can search history directly:
Ctrl-R starts an incremental reverse search — type a few
characters, and bash finds the most recent matching command as you type.
Press Ctrl-R again to step to the next (older) match.Ctrl-G (or Ctrl-C) to cancel the search and return to an empty
prompt.Ctrl-R search:
(reverse-i-search)`tail': tail -f /var/log/syslog
-- typing more of "tail" narrows the match further;
Ctrl-R again steps to an older matching command;
Enter runs it, Ctrl-G cancels
History expansion lets you reference and reuse previous commands directly by typing a short expression, without searching interactively:
| Expression | Expands to |
|---|---|
!! |
The previous command |
!n |
The command at history line number n |
!string |
The most recent command starting with string |
!?string? |
The most recent command containing string anywhere |
!$ |
The last argument of the previous command |
!* |
All arguments of the previous command |
^old^new |
Re-runs the previous command with old replaced by new |
You just ran a long command and want to reuse parts of it without retyping.
$ ls -la /var/log/nginx
... output ...
$ cd !$
cd /var/log/nginx
!$ pulled the last argument (/var/log/nginx) from the previous
command straight into the new one.
$ grep ERROR /var/log/nginx/error.log
... output ...
$ !!
grep ERROR /var/log/nginx/error.log
... reruns the exact same command ...
$ cat /etc/hosts
... output ...
$ ^hosts^hostname
cat /etc/hostname
^hosts^hostname took the previous command and substituted the first
occurrence of hosts with hostname, then ran the result.
Command-line editing and history features are convenience tools, but they carry real, everyday implications for anyone working at a shell:
~/.bash_history) in the clear, and stays there until it is explicitly
cleared. Anyone with read access to that file, or to a backup of your home
directory, can read it later.HISTCONTROL=ignorespace or similar)
to skip recording a command that starts with a space — a genuinely
useful habit for a one-off command that must include a secret, though it
depends on that shell option already being enabled.history -c clears the in-memory history for the current session, but
does not by itself guarantee the on-disk history file is scrubbed of
everything already written — clearing history after the fact is a much
weaker control than simply never typing a secret as a plain argument in the
first place.Ctrl-A/Ctrl-E (start/end of line), Ctrl-F/Ctrl-B
(character), Alt-F/Alt-B (word), Ctrl-L (clear screen).Ctrl-D/Backspace (delete), Ctrl-T/Alt-T
(transpose char/word), Alt-L/Alt-U/Alt-C (lower/upper/capitalise).Ctrl-K/Ctrl-U (kill to end/start of line), Ctrl-W/
Alt-D (kill word back/forward), Ctrl-Y (yank/paste).Ctrl-P/Ctrl-N (or arrow keys) step through
history; history lists it with line numbers.Ctrl-R for incremental reverse search, repeatable
to step to older matches; Ctrl-G cancels.!! (last command), !n (line number), !string
(starts with), !?string? (contains), !$ (last argument), !* (all
arguments), ^old^new (quick substitution and rerun).| Term | Meaning |
|---|---|
| Readline | The library bash uses for command-line editing. |
| Emacs mode | Readline's default keybinding style. |
| Kill | Readline's term for cutting text into its buffer. |
| Yank | Readline's term for pasting killed text back. |
| Kill ring | The buffer holding recently killed text. |
| Tab completion | Auto-completing commands/filenames on Tab. |
| History | The shell's stored record of previous commands. |
| Incremental search | Live-matching history as you type (Ctrl-R). |
| History expansion | Shorthand (!!, !$, etc.) to reuse past commands. |
| HISTCONTROL | A shell variable controlling what's saved to history (beyond this lesson). |
tar -czf backup.tar.gz /home/user.
Using history expansion, how would you quickly ls the same directory?history -c
give a false sense of security?ls !$ — !$ pulls /home/user, the last argument of the previous
command. Reuse the last argument directly.